﻿using System;
using System.ComponentModel.DataAnnotations;
using K9Nano.IM.Security;
using WalkingTec.Mvvm.Core;

namespace K9Nano.IM.ViewModels
{
    public abstract class Md5BaseVM : BaseVM, ISignModel
    {
        /// <summary>
        /// 签名
        /// </summary>
        [Display(Name = "签名")]
        [Required(AllowEmptyStrings = false)]
        public string Sign { get; set; }

        /// <summary>
        /// 时间戳, 秒
        /// </summary>
        [Display(Name = "时间戳")]
        [Required]
        public long Timestamp { get; set; }

        /// <summary>
        /// 需要签名的字段组成的字符串
        /// </summary>
        public abstract string GetFormatString();

        protected abstract string GetSecret();

        protected virtual int ExpiresInSecond { get; set; } = 500;

        protected virtual string FormatSalt(string text, string salt)
        {
            return $"{text}&Sign={salt}";
        }

        public virtual long GetTimestamp()
        {
            return DateTimeOffset.Now.ToUnixTimeSeconds();
        }

        public override void Validate()
        {
#if DEBUG
            if (GlobalServices.GetService<Configs>().IsQuickDebug)
            {
                return;
            }
#endif
            var format = GetFormatString();

            var secret = GetSecret();

            if (string.IsNullOrEmpty(secret))
            {
                this.MSD.AddModelError(nameof(Sign), "未配置秘钥");
            }

            var sign = Utils.GetMD5String(FormatSalt(format, secret));

            if (!string.Equals(sign, Sign))
            {
                this.MSD.AddModelError(nameof(Sign), "签名无效");
            }

            var now = GetTimestamp();
            if (now - Timestamp > ExpiresInSecond)
            {
                this.MSD.AddModelError(nameof(Sign), "签名过期");
            }
        }
    }
}